using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml.Serialization;

namespace FixedWidthFileViewer
{
    public partial class Form1 : Form
    {
        //private string[] fileLines;
        private FixedWidthSchema schema;
        private Dictionary<string, TextBox> recordFields;
        private readonly string schemaPath = Application.StartupPath + @"\schemas";
        private string currentSchemaFilename;
        private string currentDataFilename;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void saveSchema()
        {
            ensureDirectoryExists(schemaPath);
            if (currentSchemaFilename == string.Empty)
            {
                getSchemaFilenameFromUser();
            }
            XmlSerializer xs = new XmlSerializer(typeof(FixedWidthSchema));
            using (TextWriter tw = new StreamWriter(currentSchemaFilename))
            {
                xs.Serialize(tw, schema);
                tw.Close();
            }
        }

        private void getSchemaFilenameFromUser()
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.DefaultExt = ".xml";
            sfd.Filter = "XML File | *.xml";
            sfd.InitialDirectory = schemaPath;
            sfd.Title = "Save Schema File As . . .";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                currentSchemaFilename = sfd.FileName;
            }
        }

        private void setupRecordPanel()
        {
            recordFields = new Dictionary<string, TextBox>();
            recordPNL.SuspendLayout();
            recordPNL.Controls.Clear();
            int curIndex = 0;
            Label lbl;
            TextBox tb;
            int linePos, col;
            linePos = 2;
            col = recordPNL.Width / 3;
            foreach (FixedWidthField field in schema.Fields)
            {
                lbl = new Label();
                lbl.Text = field.Name + "(" + curIndex.ToString() + "," +
                    (curIndex + field.Length).ToString() + ")";
                lbl.Location = new Point(2, linePos);
                lbl.Width = col - 8;
                tb = new TextBox();
                tb.Location = new Point(col, linePos);
                tb.Width = recordPNL.Width - col - 40;
                recordPNL.Controls.Add(lbl);
                recordPNL.Controls.Add(tb);
                curIndex += field.Length;
                linePos += lbl.Height + 4;
                recordFields.Add(field.Name, tb);
            }
            recordPNL.ResumeLayout();
        }

        private void loadSchema(string schemaFilename)
        {
            currentSchemaFilename = schemaFilename;
            ensureDirectoryExists(schemaPath);
            XmlSerializer xs = new XmlSerializer(typeof(FixedWidthSchema));
            using (TextReader tr = new StreamReader(currentSchemaFilename))
            {
                schema = xs.Deserialize(tr) as FixedWidthSchema;
                tr.Close();
            }
            setupRecordPanel();
        }


        private void loadFile(string filepath)
        {
            string fileContents = File.ReadAllText(filepath);
            List<string> fileRecords = new List<string>();
            int recordLength = schema.GetRecordLength();
            int curIndex = 0;
            while ((curIndex + recordLength) < fileContents.Length)
            {
                fileRecords.Add(fileContents.Substring(curIndex, recordLength));
                curIndex += recordLength;
            }

            BindingSource bs = new BindingSource();
            bs.DataSource = fileRecords;
            linesLB.DataSource = bs;
            currentDataFilename = filepath;
        }

        private void linesLB_SelectedIndexChanged(object sender, EventArgs e)
        {
            parseAndDisplayRecord(linesLB.SelectedItem.ToString());
        }

        private void parseAndDisplayRecord(string record)
        {
            recordPNL.SuspendLayout();
            int curIndex = 0;
            TextBox tb;
            foreach (FixedWidthField field in schema.Fields)
            {
                string val = record.Substring(curIndex, field.Length);
                tb = recordFields[field.Name];
                tb.Text = val;
                curIndex += field.Length;
            }
            recordPNL.ResumeLayout();
        }

        private void recordPNL_Resize(object sender, EventArgs e)
        {

        }

        private void ensureDirectoryExists(string path)
        {
            if (Directory.Exists(path) == false)
            {
                Directory.CreateDirectory(path);
            }
        }

        private void loadSchemaBTN_Click(object sender, EventArgs e)
        {
            showLoadSchemaDialog();
        }

        private void showLoadSchemaDialog()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.DefaultExt = ".xml";
            ofd.Filter = "XML File | *.xml";
            ofd.InitialDirectory = schemaPath;
            ofd.Multiselect = false;
            ofd.Title = "Choose Schema File . . .";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                loadSchema(ofd.FileName);
                if (currentDataFilename != string.Empty && currentDataFilename != null)
                {
                    loadFile(currentDataFilename);
                }
            }
        }


        private void loadFileBTN_Click(object sender, EventArgs e)
        {
            showLoadFileDialog();
        }

        private void showLoadFileDialog()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = @"c:\";
            ofd.Multiselect = false;
            ofd.Title = "Choose Fixed Width File . . .";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                loadFile(ofd.FileName);
            }
        }

        private void editSchemaBTN_Click(object sender, EventArgs e)
        {
            if (schema == null)
            {
                showLoadSchemaDialog();
            }

            showEditSchemaDialog();
        }

        private void showEditSchemaDialog()
        {
            EditSchemaForm esf = new EditSchemaForm(schema);
            if (esf.ShowDialog() == DialogResult.OK)
            {
                saveSchema();
                setupRecordPanel();
            }
        }

        private void newBTN_Click(object sender, EventArgs e)
        {
            schema = new FixedWidthSchema();
            //schema.Fields.Add(new FixedWidthField("new field", 0));
            currentSchemaFilename = "";
            showEditSchemaDialog();
        }


        #region unused
        private void setupFields()
        {
            schema = new FixedWidthSchema();
            schema.AddField("FuncCode", 1);
            schema.AddField("ELIN", 10);
            schema.AddField("House#", 10);
            schema.AddField("House#Suffix", 4);
            schema.AddField("PrefixDirectional", 2);
            schema.AddField("StreetName", 60);
            schema.AddField("StreetSuffix", 4);
            schema.AddField("PostDirectional", 2);
            schema.AddField("Community", 32);
            schema.AddField("State", 2);
            schema.AddField("Location", 60);
            schema.AddField("CustName", 32);
            schema.AddField("ClassOfService", 1);
            schema.AddField("TypeOfService", 1);
            schema.AddField("Exchange", 4);
            schema.AddField("Esn", 5);
            schema.AddField("MainNumber", 10);
            schema.AddField("OrderNumber", 10);
            schema.AddField("ExtractDate", 6);
            schema.AddField("CountyID", 4);
            schema.AddField("DialToneProvider", 5);
            schema.AddField("SourceID", 1);
            schema.AddField("ZipCode", 5);
            schema.AddField("Zip4", 4);
            schema.AddField("GenUse", 11);
            schema.AddField("CustomerCode", 3);
            schema.AddField("Comments", 30);
            schema.AddField("XCoord", 9);
            schema.AddField("YCoord", 9);
            schema.AddField("ZCoord", 5);
            schema.AddField("CellID", 6);
            schema.AddField("SectorID", 1);
            schema.AddField("TarCode", 6);
            schema.AddField("Reserved", 21);
            schema.AddField("AltNumber", 10);
            schema.AddField("ExpandedExtractDate", 8);
            schema.AddField("NenaReserved", 86);
            schema.AddField("Reserved2", 28);
        }
        #endregion

    }
}